package dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import util.Conversion;

import dto.DomainDTO;

import entities.Domain;

/**
 * Session Bean implementation class DomainDAO
 */
@Stateless
public class DomainDAO implements DomainDAORemote {

	/**
	 * Default constructor.
	 */

	@PersistenceContext
	EntityManager em;

	public DomainDAO() {
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void addDomain(DomainDTO dDTO) throws Exception{
		try{
			Conversion c= new Conversion();
			Domain d=c.fromDomainDTOtoDomain(dDTO);
			if(getIdByDomainName(dDTO.getName())==0)
				em.persist(d);
			else
				throw new Exception("Error adding new domain - domain with name "+ dDTO.getName()+" allready exists");
		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("Error adding new domain!",e);
		}
	}

	@Override
	public void removeDomain(DomainDTO dDTO) throws Exception{
		try{

			em.remove(em.find(Domain.class,dDTO.getId()));

		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("Error adding new domain!",e);
		}
	}
	
	@Override
	public void updateDomain(DomainDTO dOldDTO,DomainDTO dNewDTO) throws Exception{
		try{
			if(getIdByDomainName(dOldDTO.getName())!=0){
				Domain d=em.find(Domain.class,dOldDTO.getName());
				d.setName(dNewDTO.getName());
				em.merge(d);
			}else{
				throw new Exception("Error updating domain - domain with name "+ dOldDTO.getName()+" to "+dNewDTO.getName());
			}
			
		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("Error updating domain!",e);
		}
	}
	
	@Override
	public List<DomainDTO> findAllDomains() {
		Conversion conv = new Conversion();
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<Domain> cq = cb.createQuery(Domain.class);
		Root<Domain> cust = cq.from(Domain.class);
		cq.select(cust);
		TypedQuery<Domain> q = em.createQuery(cq);
		List<Domain> l = q.getResultList();
		List<DomainDTO> ldto = new ArrayList<DomainDTO>();
		for (Domain t : l) {
			//System.out.println(t.getName());
	
			try {
				ldto.add(conv.fromDomainToDomainDTO(t));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return ldto;
	}

	@Override
	public int getIdByDomainName(String name) {
		TypedQuery<Domain> query = em.createQuery(
				"SELECT d FROM Domain d where d.name=:nameParam", Domain.class);
		query.setParameter("nameParam", name);
		List<Domain> resultList = query.getResultList();
		if (resultList.size() > 0)
			return resultList.get(0).getId();
		return 0;
	}
	
	@Override
	public boolean domainHasCategories(DomainDTO dDTO){
		
		
		
		TypedQuery<Domain> query = em.createQuery(
				"SELECT d FROM Domain d where d.id=:nameParam", Domain.class);
		query.setParameter("nameParam", dDTO.getId());
		List<Domain> resultList = query.getResultList();
		if (resultList.size() > 0)
			return (resultList.get(0).getCategories().size()>0);
		return false;
	}

}
